import React, { Component, Suspense } from "react";
import { connect } from "dva";
import GridContent from "@/components/PageHeaderWrapper/GridContent";
import { FormattedMessage } from "umi-plugin-react/locale";
import PageHeaderWrapper from "@/components/PageHeaderWrapper";
import PageLoading from "@/components/PageLoading";
import { Card, Button, Icon, Modal, message, Form, Input, Checkbox, Col, Row, Tag, Spin, Progress } from "antd";
import { Pie, TimelineChart, ChartCard, yuan, Field } from "@/components/Charts";
import Trend from "@/components/Trend";
import numeral from "numeral";
import echarts from "echarts/lib/echarts";
import "echarts/lib/chart/bar";
import "echarts/lib/chart/line";
import "echarts/lib/component/tooltip";
import "echarts/lib/component/title";
import "echarts/lib/component/legend";
import "echarts/lib/component/toolbox";
import "echarts/lib/component/markPoint";
import "echarts/lib/component/markLine";
import styles from "./index.less";
import img1 from "../../../assets/dialog/1.png";
import img2 from "../../../assets/dialog/2.png";
import img3 from "../../../assets/dialog/3.png";
import img4 from "../../../assets/dialog/4.png";
import SlotModal from "@/pages/Dialog/Add/slotModal";
// const SlotModal = React.lazy(() => import('./slotModal'));
const FlowPage = React.lazy(() => import("./flow"));

import DialogFlow from "@/pages/Dialog/Add/dialogFlow";
import DialogNew from "@/pages/DialogNew";
import RightDrawer from "@/pages/Dialog/common/Drawer";
import Save from "@/pages/Dialog/Add/save";
import FlowGraph from "@/pages/DialogNew/Graph";
import { cancelDialogTraining, knowledgeDialogTemplate, knowledgeDialogSlots, FetchDialogInfo } from "@/services/dialog";
import UserSession from "@/UserSession";
import ClassModal from "./classModal";

const formItemLayout = {
	labelCol: { span: 1 },
	wrapperCol: { span: 20 },
};
let myChart;

let intervalId = null;

@connect(({ DialogAdd, loading }) => ({
	DialogAdd,
	loading: loading.effects["dialogAdd/fetchSlot"],
}))
class DialogAdd extends Component {
	state = {
		visible: false, // 词槽弹窗是否显示
		limit: 5, // 词槽每页加载数量
		page: 1, // 词槽页数
		slotLoading: true, // 词槽加载loading
		slotTotal: 0, // 词槽列表总数
		slotData: [], // 词槽列表
		keys: "", // 词槽搜索关键词
		slotList: [], // 添加的词槽列表
		dialogId: "", // 多轮对话id
		name: "", // 多轮对话name
		slotDetailVisible: false,
		stageTitle: [],
		dialogData: {
			nodes: [],
			edges: [],
		},
		training: false,
		chartsIsShow: false,
		percent: 0,
		dialogObj: null,
		data: null,
		status: null,
		selectNode: {
			title: "",
			model: "",
			nodeType: "",
			id: "",
		},
		rightVisible: false,
		editName: false,
		publishTime: null,
		showClassModal: false,
	};

	componentDidMount() {
		if (this.props.location.query.id) {
			this.setState(
				{
					dialogId: this.props.location.query.id,
				},
				() => {
					this.initDialog(this.props.location.query.id);
				}
			);
		}
	}

	fetchSlot = () => {
		const { dispatch } = this.props;
		const { limit, page, keys } = this.state;
		dispatch({
			type: "dialogAdd/fetchSlot",
			payload: {
				size: limit,
				current: page,
				search: keys,
				urlPrefix: UserSession.isSystemKnowledge() ? 1 : null,
			},
			callback: (res) => {
				this.setState({
					slotTotal: res.total,
					slotData: res.records,
					slotLoading: false,
				});
			},
		});
	};

	addSlotToDialogByAdd = (slotId, add) => {
		const { dispatch } = this.props;
		const { dialogId } = this.state;
		dispatch({
			type: "dialogAdd/addSlotToDialog",
			payload: {
				dialogId,
				isAdd: add !== undefined ? add : true,
				slotId,
				refix: UserSession.isSystemKnowledge() ? 1 : null,
			},
			callback: (res) => {
				message.info("执行成功");
				this.handleCancel();
				this.fetchDialogSlotByDialogId(dialogId);
			},
		});
	};

	querySlotIsUsedByDialogAndSlotId = (slotId) => {
		const { dispatch } = this.props;
		const { dialogId } = this.state;
		dispatch({
			type: "dialogAdd/querySlotIsUsedByDialogAndSlotId",
			payload: {
				dialogId,
				slotId,
				urlPrefix: UserSession.isSystemKnowledge() ? 1 : null,
			},
			callback: (res) => {
				if (res.stageTitle.length > 0) {
					this.setState({
						slotDetailVisible: true,
						stageTitle: res.stageTitle,
					});
				} else {
					this.addSlotToDialogByAdd(slotId, false);
				}
			},
		});
	};

	addSlot = () => {
		this.fetchSlot();
		this.setState({
			visible: true,
		});
	};

	handleCancel = () => {
		this.setState({ visible: false, slotDetailVisible: false });
	};

	searchSlot = (val) => {
		this.setState({ page: 1, keys: val, slotLoading: true }, () => {
			this.fetchSlot();
		});
	};

	addSlotToDialog = (val) => {
		let { slotList } = this.state;
		let isHased = false;
		slotList.map((i) => {
			isHased = i.id === val.id;
		});
		if (isHased) {
			return message.error("该词槽已存在");
		};
		this.addSlotToDialogByAdd(val.id);
	};

	pageChange = (page) => {
		this.setState({ page, slotLoading: true }, () => {
			this.fetchSlot();
		});
	};

	handleDelSlot = (slot) => {
		this.querySlotIsUsedByDialogAndSlotId(slot.id);
	};

	forMap = (tag) => {
		const tagElem = (
			<Tag closable className={styles.slotItem} onClose={(e) => { e.preventDefault(); this.handleDelSlot(tag); }}>{tag.name}-{tag.key}</Tag>
		);
		return (
			<span key={tag._id} style={{ display: "inline-block" }}>{tagElem}</span>
		);
	};

	initDialog = (dialogId) => {
		this.getStatusById();
		this.fetchDialogDetailByDialogId(dialogId);
		this.fetchDialogSlotByDialogId(dialogId);
    this.getDialogInfo(dialogId)
	};

	getTrainResult = () => {
		const { dispatch } = this.props;
		const { dialogId, dialogObj } = this.state;
		dispatch({
			type: "dialogAdd/fetchTrainResult",
			payload: {
				dialogId,
			},
			callback: (res) => {
				let data = {
					x: [],
					y: [],
				};
				if (res.trainResults.length > 0) {
					for (let i = 0; i < res.trainResults.length; i += 1) {
						data.x.push(res.trainResults[i].stepIndex);
						data.y.push(res.trainResults[i].loss);
					}
				};
				this.setState({ dialogObj: res, data, });
			},
		});
	};

	getProgress = () => {
		const { dispatch } = this.props;
		const { dialogId } = this.state;
		dispatch({
			type: "dialogAdd/fetchProgress",
			payload: {
				dialogId,
			},
			callback: (res) => {
				if (res.data !== undefined) {
					this.setState({ percent: res.data, });
				};
				if (res.data === 100) {
					this.setState({ percent: 100, });
					setTimeout(() => {
						this.setState({ training: false, percent: 0, });
					}, 1000);
					// message.info('训练完成');
					clearInterval(intervalId);
					this.getStatusById();
					return false;
				};
				if (res.code && res.code === -1) {
					clearInterval(intervalId);
					return false;
				}
			},
		});
	};

	getStatusById = (showMessage) => {
		const { dispatch } = this.props;
		let { dialogId, training, status } = this.state;
		dispatch({
			type: "dialogAdd/fetchStatusById",
			payload: {
				dialogId,
				urlPrefix: UserSession.isSystemKnowledge() ? 1 : null,
			},
			callback: (res) => {
				// if (res.status === 2) {
				//   // 训练已完成
				//   training = false;
				//   this.getTrainResult();
				// } else if (res.status === 1) {
				//   // 训练中
				//   training = true;
				//   this.getProgress();
				//   intervalId = setInterval(this.getProgress, 5000);
				// } else if (res.status === 0) {
				//   // 未训练
				//   if (showMessage) {
				//     message.info('该多轮会话尚未开始训练，暂时没有报表');
				//   }
				// } else {
				//   // 已发布
				//   this.getTrainResult();
				// }
				this.setState({
					training,
					publishTime: res.publishTime,
					status: res.status,
				});
			},
		});
	};

	fetchDialogDetailByDialogId = async (dialogId) => {
		const { dispatch } = this.props;
		let { dialogData } = this.state;
		if (UserSession.isSystemKnowledge()) {
			let res = await knowledgeDialogTemplate({ dialogId });
			dialogData = res.dialogTemplate;
				// let { nodes } = dialogData;
				// nodes.map(node => {
				//   node.style = {
				//     fill: node.color,
				//     radius: 25,
				//   };
				//   node.labelCfg = {
				//     style: {
				//       fill: '#ffffff',
				//     },
				//   };
				//   node.size = [node.width, node.height];
				// });

				this.setState({ dialogData }, () => {
					this.DialogNew.judgeDataSource();
				});
		} else {
			dispatch({
				type: "dialogAdd/getDialog",
				payload: {
					dialogId,
					urlPrefix: UserSession.isSystemKnowledge() ? 1 : null,
				},
				callback: (res) => {
					dialogData = res.dialogTemplate;
					// let { nodes } = dialogData;
					// nodes.map(node => {
					//   node.style = {
					//     fill: node.color,
					//     radius: 25,
					//   };
					//   node.labelCfg = {
					//     style: {
					//       fill: '#ffffff',
					//     },
					//   };
					//   node.size = [node.width, node.height];
					// });
	
					this.setState({ dialogData }, () => {
						this.DialogNew.judgeDataSource();
					});
				},
			});
		}
	};

	fetchDialogSlotByDialogId = async (dialogId) => {
		const { dispatch } = this.props;
		if (UserSession.isSystemKnowledge()) {
			let res = await knowledgeDialogSlots({ dialogId })
			this.setState({
				slotList: res,
				slotLoading: false,
			});
		} else {
			dispatch({
				type: "dialogAdd/getDialogSlotsBydialogId",
				payload: {
					dialogId,
					urlPrefix: UserSession.isSystemKnowledge() ? 1 : null,
				},
				callback: (res) => {
					this.setState({
						slotList: res,
						slotLoading: false,
					});
				},
			});
		}
	};

	closeChart = (e) => {
		this.setState({ chartsIsShow: false, });
	};

	showTrainRes = () => {
		this.setState({ chartsIsShow: true, }, () => {
			this.getStatusById(true);
			// this.getTrainResult();
		});
	};

	showTrainPro = () => {
		this.setState({ training: true, }, () => {
			// this.getProgress();
			intervalId = setInterval(this.getProgress, 5000);
		});
	};

	initEcharts = (obj) => {
		myChart = echarts.init(document.getElementById(obj.id));
		this.chartsSetOpt(this.state.data);
	};

	chartsSetOpt = (data) => {
		myChart.setOption({
			title: { text: "" },
			toolbox: {
				show: false,
			},
			tooltip: {
				trigger: "axis",
			},
			xAxis: [
				{
					type: "category",
					data: data.x,
					name: "训练次数",
				},
			],
			yAxis: [
				{
					type: "value",
					name: "误差值",
				},
			],
			series: [
				{
					name: "",
					type: "line",
					data: data.y,
					smooth: true,
				},
			],
		});
	};

	modalRef = (obj) => {
		if (obj && this.state.dialogObj !== null) {
			this.initEcharts(obj);
		}
	};

	checkName = () => {
		const { dispatch } = this.props;
		const { dialogId, name } = this.state;
		if (name.length > 20) {
			return message.info("多轮对话名称不能超过20个字");
		};
		dispatch({
			type: "dialogAdd/updateDialogNameById",
			payload: {
				dialogId,
				dialogName: name,
			},
			callback: (res) => {
				if (!res.code) {
					this.setState({ editName: false, }, () => {
						message.info(res.msg);
					});
				}
			},
		});
	};

	fixName = (e) => {
		if (e.target.value.length > 20) {
			return message.info("多轮对话名称不能超过20个字符");
		};
		this.setState({ name: e.target.value, });
	};

	backList = () => {
		window.location.href = "/dialog/index";
	};

	/**
	 * 打开右边弹窗
	 * @returns {*}
	 */
	opRightDrawer = (selectNode) => {
		this.setState({ selectNode, rightVisible: true, }, () => {
			this.RightDrawer.checkAction();
		});
	};

	/**
	 * 关闭右边弹框
	 */
	onCloseRight = () => {
		this.setState({ rightVisible: false, });
	};

	/**
	 * 取消训练
	 */
	cancelTraining = async () => {
		const { dialogId } = this.state;

		const res = await cancelDialogTraining({ dialogId });
		this.setState({ training: false, }, () => {
			clearInterval(intervalId);
			// this.getStatusById();
		});
	};

  /**
   * 
   * @returns 获取多轮会话基础信息
   */
  getDialogInfo = async () => {
    const dialogId = this.props.location.query.id
    const res = await FetchDialogInfo({id:dialogId})
    this.setState({
      name:res.name
    })
  }

  /**
   * 
   * @returns 打开移动分类弹窗
   */
  openMoveClass = () => {
    this.setState({
      showClassModal:true
    })
  }

	render() {
		const { getFieldDecorator } = this.props.form;
		const { graph } = FlowGraph;

		const {
			visible,
			slotLoading,
			slotData,
			slotTotal,
			slotList,
			name,
			slotDetailVisible,
			stageTitle,
			dialogId,
			dialogData,
			training,
			chartsIsShow,
			percent,
			dialogObj,
			status,
			selectNode,
			rightVisible,
			editName,
			publishTime,
		} = this.state;
		const tagChild = slotList.map(this.forMap);
		const { match: { params: { id }, }, location: { query: { categoryId,libraryQuery },pathname }, } = this.props;
    const platformInfo = window.localStorage.getItem("platformInfo") ? JSON.parse(window.localStorage.getItem("platformInfo")) : {}

		return (
			<div style={{ width: "100%",height:platformInfo.bottomInfo ? 'calc(100vh - 150px)' : 'calc(100vh - 100px)' }} id={"dialogContent"}>
				{/*<Suspense fallback={<PageLoading />}>*/}
				{/*  <PageHeaderWrapper>*/}
				{
        //   <Card className={styles.dialogTop}>
				// 	<Row>
				// 		<Col span={12}>
				// 			{editName ? (
				// 				<Form layout={"inline"}>
				// 					<Form.Item label={"名称"}>
				// 						{getFieldDecorator("name", {
				// 							rules: [
				// 								{ required: true, message: "请输入多轮对话名称", },
				// 							],
				// 							initialValue: name,
				// 						})(
				// 							<Input placeholder='请输入多轮对话名称' onChange={(e) => this.fixName(e)} />
				// 						)}
				// 					</Form.Item>
				// 					<Form.Item>
				// 						<Button type='primary' size='small' onClick={() => this.checkName()}>保存</Button>
				// 					</Form.Item>
				// 					<Form.Item>
				// 						<Button size='small' onClick={() => this.setState({ editName: false })}>取消</Button>
				// 					</Form.Item>
				// 				</Form>
				// 			) : (
				// 				<div className={styles.title} style={{ padding: 0 }}>
				// 					<span>
				// 						{name}
				// 						{/* 系统知识库不显示编辑多轮名称 */}
				// 						{
				// 							!UserSession.isSystemKnowledge() && (
				// 								<Icon
				// 									type={"form"}
				// 									style={{ marginLeft: 10 }}
				// 									onClick={() => this.setState({ editName: true })}
				// 								/>
				// 							)
				// 						}

				// 						{/* 系统知识库不显示移动分类 */}
				// 						{!UserSession.isSystemKnowledge() && (
				// 							<Icon
				// 								type='unordered-list'
				// 								style={{ marginLeft: 10, cursor: "pointer" }}
				// 								onClick={() => this.setState({ showClassModal: true })}
				// 							/>
				// 						)}
				// 					</span>
				// 				</div>
				// 			)}
				// 		</Col>
				// 		<Col span={12}>
				// 			<Save
				// 				dialogId={dialogId}
				// 				showTrain={this.showTrainPro}
				// 				graphObj={graph}
				// 				status={status}
				// 				publishTime={publishTime}
				// 				getStatusById={this.getStatusById}
				// 			/>
				// 		</Col>
				// 	</Row>
				// </Card>
        }
				<Card bodyStyle={{ padding: 0,height:"100%" }} className={styles.dialogBody}>
					<DialogNew
						dialogId={dialogId}
						showCharts={this.showTrainRes}
						showTrains={this.showTrainPro}
						dialogData={dialogData}
						opRightDrawer={this.opRightDrawer}
						onRef={(ref) => (this.DialogNew = ref)}
						getDialogData={() => this.fetchDialogDetailByDialogId(dialogId)}
            status={status}
            publishTime={publishTime}
            getStatusById={this.getStatusById}
            name={name}
            refreshName={this.getDialogInfo}
            openMoveClass={this.openMoveClass}
            pathInfo={{pathname,id,query:this.props.location.query}}
            
					/>
				</Card>

				<RightDrawer
					title={selectNode.title}
					model={selectNode.model}
					visible={rightVisible}
					dialogId={dialogId}
					onClosed={this.onCloseRight}
					nodeIds={selectNode.id}
					slotList={slotList}
					slotLoading={slotLoading}
					addSlot={this.addSlot}
					handleDelSlot={this.handleDelSlot}
					onRef={(ref) => (this.RightDrawer = ref)}
				/>

				<SlotModal
					total={slotTotal}
					visible={visible}
					listData={slotData}
					loading={slotLoading}
					alreadyExisted={slotList}
					onCancel={this.handleCancel}
					searchSlot={this.searchSlot}
					pageChange={this.pageChange}
					addSlot={this.addSlotToDialog}
				/>
				<Modal title='词槽使用详情' visible={slotDetailVisible} onOk={this.handleCancel} onCancel={this.handleCancel}>
					<p style={{ textAlign: "center" }}>
						{" "}
						该词槽正在被以下模块使用，不可删除
					</p>
					{stageTitle.map((item, index) => {
						return (
							<p key={index} style={{ color: "lightblue", textAlign: "center" }}>{item}</p>
						);
					})}
				</Modal>
				<Modal
					title=''
					centered
					footer={null}
					closable={false}
					visible={training}>
					<p style={{ textAlign: "center" }}>多轮对话训练中...</p>
					<div style={{ textAlign: "center" }}>
						<Progress type='circle' percent={percent} style={{ margin: "0 auto" }} width={80} />
					</div>
					<div style={{ textAlign: "center" }}>
						<Button onClick={() => this.backList()} style={{ marginTop: 20 }}>
							<Icon type='rollback' />
							返回多轮会话列表
						</Button>
						<Button onClick={() => this.cancelTraining()} style={{ marginTop: 20, marginLeft: 10 }}>
							<Icon type='stop' />
							取消训练
						</Button>
					</div>
				</Modal>
				{dialogObj !== null ? (
					<Modal
						title=''
						centered
						footer={null}
						visible={chartsIsShow}
						onCancel={this.closeChart}
						width={773}>
						<div className={styles.trainResBox}>
							<div className={styles.head}>
								<div className={styles.title}>
									<img src={img1} alt='' style={{ height: 30, marginLeft: 10, marginTop: 8 }} />
									<h3 style={{ color: "#445474", textAlign: "center", marginTop: 10, marginLeft: 10 }}>训练完成</h3>
								</div>
							</div>
							<div className={styles.body}>
								<Row>
									<h3>训练结果</h3>
								</Row>
								<Row>
									<h4 className={styles.time}>
										训练时间{dialogObj.fromFormat} 至 {dialogObj.toFormat}
									</h4>
								</Row>
								<Row>
									<Col span={8}>
										<ChartCard
											title='训练时长'
											avatar={
												<img alt='indicator' style={{ width: 56, height: 56 }} src={img2} />
											}
											total={() => (
												<span style={{ fontSize: 25 }} dangerouslySetInnerHTML={{ __html: dialogObj.allTime + "秒", }} />
											)}
											footer={null}
											contentHeight={46}
										/>
									</Col>
									<Col span={8}>
										<ChartCard
											title='迭代'
											total={() => (
												<span style={{ fontSize: 25 }} dangerouslySetInnerHTML={{ __html: dialogObj.epochIndex + "次", }} />
											)}
											footer={null}
											avatar={
												<img alt='indicator' style={{ width: 56, height: 56 }} src={img3} />
											}
											contentHeight={46}
										/>
									</Col>
									<Col span={8}>
										<ChartCard
											title='准确率'
											total={() => (
												<span
													style={{ fontSize: 25 }}
													dangerouslySetInnerHTML={{
														__html: (dialogObj.acc * 100).toFixed(2) + "%",
													}}
												/>
											)}
											footer={null}
											avatar={
												<img alt='indicator' style={{ width: 56, height: 56 }} src={img4} />
											}
											contentHeight={46}
										/>
									</Col>
								</Row>
								<Row style={{ marginTop: 20 }}>
									<h3>误差曲线</h3>
								</Row>
								<div className={styles.charts}>
									<div id='main' style={{ width: "100%", height: 350 }} ref={this.modalRef} />
								</div>
							</div>
						</div>
					</Modal>
				) : (
					""
				)}
				<ClassModal
					id={id}
					dialogId={this.props.location.query.id}
					visible={this.state.showClassModal}
					dispatch={this.props.dispatch}
					categoryId={categoryId}
					handleCancel={() => {
						this.setState({ showClassModal: false });
					}}
				/>
				{/*  </PageHeaderWrapper>*/}
				{/*</Suspense>*/}
			</div>
		);
	}
}

export default connect(({ user }) => ({
	currentUser: user.currentUser,
}))(Form.create()(DialogAdd));
